home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / occmgr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  20.7 KB  |  775 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #ifdef MACOCX
  13. #define DBINITCONSTANTS
  14. #endif
  15. #include "occimpl.h"
  16. #include "ocdb.h"
  17.  
  18. #ifdef AFX_OCC_SEG
  19. #pragma code_seg(AFX_OCC_SEG)
  20. #endif
  21.  
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. #define new DEBUG_NEW
  28.  
  29. #ifndef _AFX_NO_OCC_SUPPORT
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32. // AfxEnableControlContainer - wire up control container functions
  33.  
  34. PROCESS_LOCAL(COccManager, _afxOccManager)
  35.  
  36. void AFX_CDECL AfxEnableControlContainer(COccManager* pOccManager)
  37. {
  38.     if (pOccManager == NULL)
  39.         afxOccManager = _afxOccManager.GetData();
  40.     else
  41.         afxOccManager = pOccManager;
  42. }
  43.  
  44. /////////////////////////////////////////////////////////////////////////////
  45. // Helper functions for cracking dialog templates
  46.  
  47. static inline BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
  48. {
  49.     return ((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
  50. }
  51.  
  52. static inline WORD& DlgTemplateItemCount(DLGTEMPLATE* pTemplate)
  53. {
  54.     if (IsDialogEx(pTemplate))
  55.         return reinterpret_cast<DLGTEMPLATEEX*>(pTemplate)->cDlgItems;
  56.     else
  57.         return pTemplate->cdit;
  58. }
  59.  
  60. static inline const WORD& DlgTemplateItemCount(const DLGTEMPLATE* pTemplate)
  61. {
  62.     if (IsDialogEx(pTemplate))
  63.         return reinterpret_cast<const DLGTEMPLATEEX*>(pTemplate)->cDlgItems;
  64.     else
  65.         return pTemplate->cdit;
  66. }
  67.  
  68. AFX_STATIC DLGITEMTEMPLATE* AFXAPI _AfxFindFirstDlgItem(const DLGTEMPLATE* pTemplate)
  69. {
  70.     DWORD dwStyle = pTemplate->style;
  71.     BOOL bDialogEx = IsDialogEx(pTemplate);
  72.  
  73.     WORD* pw;
  74.     if (bDialogEx)
  75.     {
  76.         pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1);
  77.         dwStyle = ((DLGTEMPLATEEX*)pTemplate)->style;
  78.     }
  79.     else
  80.     {
  81.         pw = (WORD*)(pTemplate + 1);
  82.     }
  83.  
  84.     if (*pw == (WORD)-1)        // Skip menu name ordinal or string
  85.         pw += 2; // WORDs
  86.     else
  87.         while (*pw++);
  88.  
  89.     if (*pw == (WORD)-1)        // Skip class name ordinal or string
  90.         pw += 2; // WORDs
  91.     else
  92.         while (*pw++);
  93.  
  94.     while (*pw++);              // Skip caption string
  95.  
  96.     if (dwStyle & DS_SETFONT)
  97.     {
  98.         pw += bDialogEx ? 3 : 1;    // Skip font size, weight, (italic, charset)
  99.         while (*pw++);              // Skip font name
  100.     }
  101.  
  102.     // Dword-align and return
  103.     return (DLGITEMTEMPLATE*)(((DWORD)pw + 3) & ~3);
  104. }
  105.  
  106. AFX_STATIC DLGITEMTEMPLATE* AFXAPI _AfxFindNextDlgItem(DLGITEMTEMPLATE* pItem, BOOL bDialogEx)
  107. {
  108.     WORD* pw;
  109.  
  110.     if (bDialogEx)
  111.         pw = (WORD*)((DLGITEMTEMPLATEEX*)pItem + 1);
  112.     else
  113.         pw = (WORD*)(pItem + 1);
  114.  
  115.     if (*pw == (WORD)-1)            // Skip class name ordinal or string
  116.         pw += 2; // WORDs
  117.     else
  118.         while (*pw++);
  119.  
  120.     if (*pw == (WORD)-1)            // Skip text ordinal or string
  121.         pw += 2; // WORDs
  122.     else
  123.         while (*pw++);
  124.  
  125.     WORD cbExtra = *pw++;           // Skip extra data
  126.  
  127.     // Dword-align and return
  128.     return (DLGITEMTEMPLATE*)(((DWORD)pw + cbExtra + 3) & ~3);
  129. }
  130.  
  131. /////////////////////////////////////////////////////////////////////////////
  132. // COccManager
  133.  
  134. BOOL COccManager::OnEvent(CCmdTarget* pCmdTarget, UINT idCtrl,
  135.     AFX_EVENT* pEvent, AFX_CMDHANDLERINFO* pHandlerInfo)
  136. {
  137.     return pCmdTarget->OnEvent(idCtrl, pEvent, pHandlerInfo);
  138. }
  139.  
  140. COleControlContainer* COccManager::CreateContainer(CWnd* pWnd)
  141. {
  142.     // advanced control container apps may want to override
  143.     return new COleControlContainer(pWnd);
  144. }
  145.  
  146. COleControlSite* COccManager::CreateSite(COleControlContainer* pCtrlCont)
  147. {
  148.     // advanced control container apps may want to override
  149.     return new COleControlSite(pCtrlCont);
  150. }
  151.  
  152. const DLGTEMPLATE* COccManager::PreCreateDialog(_AFX_OCC_DIALOG_INFO* pDlgInfo,
  153.     const DLGTEMPLATE* pOrigTemplate)
  154. {
  155.     ASSERT(pDlgInfo != NULL);
  156.  
  157.     pDlgInfo->m_ppOleDlgItems =
  158.         (DLGITEMTEMPLATE**)malloc(sizeof(DLGITEMTEMPLATE*) *
  159.             (DlgTemplateItemCount(pOrigTemplate) + 1));
  160.  
  161.     if (pDlgInfo->m_ppOleDlgItems == NULL)
  162.         return NULL;
  163.  
  164. #if defined(_WIN32_WCE)
  165.     pDlgInfo->m_bDialogEx = IsDialogEx(pOrigTemplate); // See header for explanation
  166. #endif // _WIN32_WCE
  167.     DLGTEMPLATE* pNewTemplate = SplitDialogTemplate(pOrigTemplate,
  168.         pDlgInfo->m_ppOleDlgItems);
  169.     pDlgInfo->m_pNewTemplate = pNewTemplate;
  170.  
  171.     return (pNewTemplate != NULL) ? pNewTemplate : pOrigTemplate;
  172. }
  173.  
  174. void COccManager::PostCreateDialog(_AFX_OCC_DIALOG_INFO* pDlgInfo)
  175. {
  176.     if (pDlgInfo->m_pNewTemplate != NULL)
  177.         WCE_FCTN(GlobalFree)(pDlgInfo->m_pNewTemplate);
  178.  
  179.     if (pDlgInfo->m_ppOleDlgItems != NULL)
  180.         free(pDlgInfo->m_ppOleDlgItems);
  181. }
  182.  
  183. DLGTEMPLATE* COccManager::SplitDialogTemplate(const DLGTEMPLATE* pTemplate,
  184.     DLGITEMTEMPLATE** ppOleDlgItems)
  185. {
  186.     DLGITEMTEMPLATE* pFirstItem = _AfxFindFirstDlgItem(pTemplate);
  187.     ULONG cbHeader = (BYTE*)pFirstItem - (BYTE*)pTemplate;
  188.     ULONG cbNewTemplate = cbHeader;
  189.  
  190.     BOOL bDialogEx = IsDialogEx(pTemplate);
  191.  
  192.     int iItem;
  193.     int nItems = (int)DlgTemplateItemCount(pTemplate);
  194.     DLGITEMTEMPLATE* pItem = pFirstItem;
  195.     DLGITEMTEMPLATE* pNextItem = pItem;
  196. #ifndef OLE2ANSI
  197.     LPWSTR pszClassName;
  198. #else
  199.     LPSTR pszClassName;
  200. #endif
  201.     BOOL bHasOleControls = FALSE;
  202.  
  203.     // Make first pass through the dialog template.  On this pass, we're
  204.     // interested in determining:
  205.     //    1. Does this template contain any OLE controls?
  206.     //    2. If so, how large a buffer is needed for a template containing
  207.     //       only the non-OLE controls?
  208.  
  209.     for (iItem = 0; iItem < nItems; iItem++)
  210.     {
  211.         pNextItem = _AfxFindNextDlgItem(pItem, bDialogEx);
  212.  
  213.         pszClassName = bDialogEx ?
  214. #ifndef OLE2ANSI
  215.             (LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  216.             (LPWSTR)(pItem + 1);
  217. #else
  218.             (LPSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  219.             (LPSTR)(pItem + 1);
  220. #endif
  221.  
  222. #ifndef OLE2ANSI
  223.         if (pszClassName[0] == L'{')
  224. #else
  225.         if (pszClassName[0] == '{')
  226. #endif
  227.         {
  228.             // Item is an OLE control.
  229.             bHasOleControls = TRUE;
  230.         }
  231.         else
  232.         {
  233.             // Item is not an OLE control: make room for it in new template.
  234.             cbNewTemplate += (BYTE*)pNextItem - (BYTE*)pItem;
  235.         }
  236.  
  237.         pItem = pNextItem;
  238.     }
  239.  
  240.     // No OLE controls were found, so there's no reason to go any further.
  241.     if (!bHasOleControls)
  242.     {
  243.         ppOleDlgItems[0] = (DLGITEMTEMPLATE*)(-1);
  244.         return NULL;
  245.     }
  246.  
  247.     // Copy entire header into new template.
  248.     BYTE* pNew = (BYTE*)WCE_FCTN(GlobalAlloc)(GMEM_FIXED, cbNewTemplate); 
  249.     DLGTEMPLATE* pNewTemplate = (DLGTEMPLATE*)pNew;
  250. #if defined(_WIN32_WCE)
  251.     if(bDialogEx)
  252.     {
  253.         // At this point, cbNewTemplate is bigger than needed, but that's okay.
  254.         BYTE* wce_convertDialogTemplate(DLGTEMPLATE*,DLGTEMPLATEEX*,ULONG);    
  255.         pNew = wce_convertDialogTemplate((DLGTEMPLATE*)pNewTemplate,
  256.                              (DLGTEMPLATEEX*)pTemplate,cbHeader); 
  257.     }
  258.     else
  259.     {
  260.         memcpy(pNew, pTemplate, cbHeader);
  261.         pNew += cbHeader;
  262.     }
  263. #else // _WIN32_WCE
  264.     memcpy(pNew, pTemplate, cbHeader);
  265.     pNew += cbHeader;
  266. #endif // _WIN32_WCE
  267.  
  268.     // Initialize item count in new header to zero.
  269.     DlgTemplateItemCount(pNewTemplate) = 0;
  270.  
  271.     pItem = pFirstItem;
  272.     pNextItem = pItem;
  273.  
  274.     // Second pass through the dialog template.  On this pass, we want to:
  275.     //    1. Copy all the non-OLE controls into the new template.
  276.     //    2. Build an array of item templates for the OLE controls.
  277.  
  278.     for (iItem = 0; iItem < nItems; iItem++)
  279.     {
  280.         pNextItem = _AfxFindNextDlgItem(pItem, bDialogEx);
  281.  
  282.         pszClassName = bDialogEx ?
  283. #ifndef OLE2ANSI
  284.             (LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  285.             (LPWSTR)(pItem + 1);
  286.  
  287.         if (pszClassName[0] == L'{')
  288. #else
  289.             (LPSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  290.             (LPSTR)(pItem + 1);
  291.  
  292.         if (pszClassName[0] == '{')
  293. #endif
  294.         {
  295.             // Item is OLE control: add it to the array.
  296.             ppOleDlgItems[iItem] = pItem;
  297.         }
  298.         else
  299.         {
  300.             // Item is not an OLE control: copy it to the new template.
  301.             ULONG cbItem = (BYTE*)pNextItem - (BYTE*)pItem;
  302.             ASSERT(cbItem >= (size_t)(bDialogEx ?
  303.                 sizeof(DLGITEMTEMPLATEEX) :
  304.                 sizeof(DLGITEMTEMPLATE)));
  305. #if defined(_WIN32_WCE)
  306.             if(bDialogEx) 
  307.             {
  308.                 BYTE* wce_convertDialogItemTemplate(DLGITEMTEMPLATE*,DLGITEMTEMPLATEEX*,ULONG); 
  309.                 pNew = wce_convertDialogItemTemplate((DLGITEMTEMPLATE*)pNew,
  310.                                                      (DLGITEMTEMPLATEEX*)pItem,cbItem);
  311.             }
  312.             else
  313.             {
  314.                 memcpy(pNew, pItem, cbItem);
  315.                 pNew += cbItem;
  316.             }
  317. #else // _WIN32_WCE
  318.             memcpy(pNew, pItem, cbItem);
  319.             pNew += cbItem;
  320. #endif // _WIN32_WCE
  321.  
  322.             // Incrememt item count in new header.
  323.             ++DlgTemplateItemCount(pNewTemplate);
  324.  
  325.             // Put placeholder in OLE item array.
  326.             ppOleDlgItems[iItem] = NULL;
  327.         }
  328.  
  329.         pItem = pNextItem;
  330.     }
  331.     ppOleDlgItems[nItems] = (DLGITEMTEMPLATE*)(-1);
  332.  
  333.     return pNewTemplate;
  334. }
  335.  
  336. BOOL COccManager::CreateDlgControls(CWnd* pWndParent, LPCTSTR lpszResourceName,
  337.     _AFX_OCC_DIALOG_INFO* pOccDlgInfo)
  338. {
  339.     // find resource handle
  340.     void* lpResource = NULL;
  341.     HGLOBAL hResource = NULL;
  342.     if (lpszResourceName != NULL)
  343.     {
  344.         HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_DLGINIT);
  345.         HRSRC hDlgInit = ::FindResource(hInst, lpszResourceName, RT_DLGINIT);
  346.         if (hDlgInit != NULL)
  347.         {
  348.             // load it
  349.             hResource = LoadResource(hInst, hDlgInit);
  350.             if (hResource == NULL)
  351.             {
  352.                 TRACE0("DLGINIT resource was found, but could not be loaded.\n");
  353.                 return FALSE;
  354.             }
  355.  
  356.             // lock it
  357.             lpResource = LockResource(hResource);
  358.             ASSERT(lpResource != NULL);
  359.         }
  360. #ifdef _DEBUG
  361.         else
  362.         {
  363.             // If we didn't find a DLGINIT resource, check whether we were
  364.             // expecting to find one
  365.             DLGITEMTEMPLATE** ppOleDlgItems = pOccDlgInfo->m_ppOleDlgItems;
  366.             ASSERT(ppOleDlgItems != NULL);
  367.  
  368.             while (*ppOleDlgItems != (DLGITEMTEMPLATE*)-1)
  369.             {
  370.                 if (*ppOleDlgItems != NULL)
  371.                 {
  372.                     TRACE0("Dialog has OLE controls, but no matching DLGINIT resource.\n");
  373.                     break;
  374.                 }
  375.                 ++ppOleDlgItems;
  376.             }
  377.         }
  378. #endif
  379.     }
  380.  
  381.     // execute it
  382.     BOOL bResult = TRUE;
  383.     if (lpResource != NULL)
  384.         bResult = CreateDlgControls(pWndParent, lpResource, pOccDlgInfo);
  385.  
  386.     // cleanup
  387.     if (lpResource != NULL && hResource != NULL)
  388.     {
  389.         UnlockResource(hResource);
  390.         FreeResource(hResource);
  391.     }
  392.  
  393.     return bResult;
  394. }
  395.  
  396. BOOL COccManager::CreateDlgControls(CWnd* pWndParent, void* lpResource,
  397.     _AFX_OCC_DIALOG_INFO* pOccDlgInfo)
  398. {
  399.     // if there are no OLE controls in this dialog, then there's nothing to do
  400.     if (pOccDlgInfo->m_pNewTemplate == NULL)
  401.         return TRUE;
  402.  
  403.     ASSERT(pWndParent != NULL);
  404.     HWND hwParent = pWndParent->GetSafeHwnd();
  405.  
  406.     BOOL bDialogEx = WCE_IF(pOccDlgInfo->m_bDialogEx, IsDialogEx(pOccDlgInfo->m_pNewTemplate));
  407.     BOOL bSuccess = TRUE;
  408.     if (lpResource != NULL)
  409.     {
  410.         ASSERT(pOccDlgInfo != NULL);
  411.         ASSERT(pOccDlgInfo->m_ppOleDlgItems != NULL);
  412.  
  413.         DLGITEMTEMPLATE** ppOleDlgItems = pOccDlgInfo->m_ppOleDlgItems;
  414.  
  415.         UNALIGNED WORD* lpnRes = (WORD*)lpResource;
  416.         int iItem = 0;
  417.         HWND hwAfter = HWND_TOP;
  418.         while (bSuccess && *lpnRes != 0)
  419.         {
  420.             WORD nIDC = *lpnRes++;
  421.             WORD nMsg = *lpnRes++;
  422. #if defined(_WIN32_WCE)
  423.             DWORD dwLen = *(UNALIGNED DWORD*)lpnRes;
  424.             lpnRes += 2;
  425. #else // _WIN32_WCE
  426.             DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;
  427. #endif // _WIN32_WCE
  428.  
  429.             #define WIN16_LB_ADDSTRING  0x0401
  430.             #define WIN16_CB_ADDSTRING  0x0403
  431.  
  432.             ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING ||
  433.                 nMsg == WIN16_LB_ADDSTRING || nMsg == WIN16_CB_ADDSTRING ||
  434.                 nMsg == WM_OCC_LOADFROMSTREAM ||
  435.                 nMsg == WM_OCC_LOADFROMSTREAM_EX ||
  436.                 nMsg == WM_OCC_LOADFROMSTORAGE ||
  437.                 nMsg == WM_OCC_LOADFROMSTORAGE_EX ||
  438.                 nMsg == WM_OCC_INITNEW);
  439.  
  440.             if (nMsg == WM_OCC_LOADFROMSTREAM ||
  441.                 nMsg == WM_OCC_LOADFROMSTREAM_EX ||
  442.                 nMsg == WM_OCC_LOADFROMSTORAGE ||
  443.                 nMsg == WM_OCC_LOADFROMSTORAGE_EX ||
  444.                 nMsg == WM_OCC_INITNEW)
  445.             {
  446.                 // Locate the DLGITEMTEMPLATE for the new control, and the control
  447.                 // that should precede it in z-order.
  448.                 DLGITEMTEMPLATE* pDlgItem;
  449.                 while (((pDlgItem = ppOleDlgItems[iItem++]) == NULL) &&
  450.                     (pDlgItem != (DLGITEMTEMPLATE*)(-1)))
  451.                 {
  452.                     if (hwAfter == HWND_TOP)
  453.                         hwAfter = GetWindow(hwParent, GW_CHILD);
  454.                     else
  455.                         hwAfter = GetWindow(hwAfter, GW_HWNDNEXT);
  456.  
  457.                     ASSERT(hwAfter != NULL);  // enough non-OLE controls?
  458.                 }
  459.  
  460.                 ASSERT(pDlgItem != NULL);   // enough dialog item templates?
  461.  
  462.                 HWND hwNew = NULL;
  463.                 if (pDlgItem != (DLGITEMTEMPLATE*)(-1))
  464.                 {
  465. #ifdef _DEBUG
  466.                     WORD id = bDialogEx ?
  467.                         (WORD)((DLGITEMTEMPLATEEX*)pDlgItem)->id :
  468.                         pDlgItem->id;
  469.                     ASSERT(id == nIDC); // make sure control IDs match!
  470. #endif
  471.  
  472.                     // Create the OLE control now.
  473.                     hwNew = CreateDlgControl(pWndParent, hwAfter, bDialogEx,
  474.                         pDlgItem, nMsg, (BYTE*)lpnRes, dwLen);
  475.                 }
  476.  
  477.                 if (hwNew != NULL)
  478.                 {
  479. #if !defined(_WIN32_WCE)
  480.                     if (bDialogEx)
  481.                         SetWindowContextHelpId(hwNew,
  482.                             ((DLGITEMTEMPLATEEX*)pDlgItem)->helpID);
  483. #endif // _WIN32_WCE
  484.                     if (GetParent(hwNew) == hwParent)
  485.                         hwAfter = hwNew;
  486.                 }
  487.                 else
  488.                     bSuccess = FALSE;
  489.             }
  490.  
  491.             // skip past data
  492.             lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
  493.         }
  494.     }
  495.  
  496.     if (bSuccess)
  497.     {
  498.         // unfreeze events now that all controls are loaded
  499.         if (pWndParent->m_pCtrlCont != NULL)
  500.             pWndParent->m_pCtrlCont->FreezeAllEvents(FALSE);
  501.  
  502. #if !defined(_WIN32_WCE)
  503.         BindControls(pWndParent);
  504. #endif // _WIN32_WCE
  505.     }
  506.  
  507.     return bSuccess;
  508. }
  509.  
  510.  
  511. #if !defined(_WIN32_WCE)
  512. void COccManager::BindControls(CWnd* pWndParent)
  513. {
  514.     HWND hWnd;
  515.     COleControlSite* pSite;
  516.  
  517.     if (pWndParent->m_pCtrlCont != NULL)
  518.     {
  519.         // Now initialize bound controls
  520.         POSITION pos = pWndParent->m_pCtrlCont->m_siteMap.GetStartPosition();
  521.         while (pos != NULL)
  522.         {
  523.             pWndParent->m_pCtrlCont->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  524.  
  525.             // For each cursor bound property initialize pClientSite ptr and bind to DSC
  526.             CDataBoundProperty* pBinding = pSite->m_pBindings;
  527.             if(pBinding)
  528.             {
  529.                 while(pBinding)
  530.                 {
  531.                     pBinding->SetClientSite(pSite);
  532.                     if (pBinding->m_ctlid != 0)
  533.                     {
  534.                         CWnd* pWnd = pWndParent->GetDlgItem(pBinding->m_ctlid);
  535.                         ASSERT(pWnd);
  536.                         ASSERT(pWnd->m_pCtrlSite);
  537.                         pBinding->SetDSCSite(pWnd->m_pCtrlSite);
  538.                     }
  539.                     pBinding = pSite->m_pBindings->GetNext();
  540.                 }
  541.             }
  542.  
  543.             // Bind default bound property
  544.             if (pSite->m_ctlidRowSource != NULL)
  545.             {
  546.                 CWnd* pWnd = pWndParent->GetDlgItem(pSite->m_ctlidRowSource);
  547.                 ASSERT(pWnd);  // gotta be a legitimate control id
  548.                 ASSERT(pWnd->m_pCtrlSite);  // and it has to be an OLE Control
  549.  
  550.                 pWnd->m_pCtrlSite->EnableDSC();
  551.  
  552.                 ASSERT(pWnd->m_pCtrlSite->m_pDataSourceControl);  // and a Data Source Control
  553.                 pSite->m_pDSCSite = pWnd->m_pCtrlSite;
  554.                 pWnd->m_pCtrlSite->m_pDataSourceControl->BindProp(pSite);
  555.             }
  556.         }
  557.  
  558.         // Finally, set up bindings on all DataSource controls
  559.         pos = pWndParent->m_pCtrlCont->m_siteMap.GetStartPosition();
  560.         while (pos != NULL)
  561.         {
  562.             pWndParent->m_pCtrlCont->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  563.             if (pSite->m_pDataSourceControl)
  564.                 pSite->m_pDataSourceControl->BindColumns();
  565.         }
  566.     }
  567. }
  568. #endif // _WIN32_WCE
  569.  
  570.  
  571. HWND COccManager::CreateDlgControl(CWnd* pWndParent, HWND hwAfter,
  572.     BOOL bDialogEx, LPDLGITEMTEMPLATE pItem, WORD nMsg, BYTE* lpData, DWORD cb)
  573. {
  574. #ifndef OLE2ANSI
  575.     LPWSTR pszClass = (LPWSTR)(pItem + 1);
  576. #else
  577.     LPSTR pszClass = (LPSTR)(pItem + 1);
  578. #endif
  579.     DLGITEMTEMPLATE dlgItemTmp;
  580.  
  581.     if (bDialogEx)
  582.     {
  583.         // We have an extended dialog template: copy relevant parts into an
  584.         // ordinary dialog template, because their layouts are different
  585.         DLGITEMTEMPLATEEX* pItemEx = (DLGITEMTEMPLATEEX*)pItem;
  586.         dlgItemTmp.style = pItemEx->style;
  587.         dlgItemTmp.dwExtendedStyle = pItemEx->exStyle;
  588.         dlgItemTmp.x = pItemEx->x;
  589.         dlgItemTmp.y = pItemEx->y;
  590.         dlgItemTmp.cx = pItemEx->cx;
  591.         dlgItemTmp.cy = pItemEx->cy;
  592.         dlgItemTmp.id = (WORD)pItemEx->id;
  593.         pItem = &dlgItemTmp;
  594. #ifndef OLE2ANSI
  595.         pszClass = (LPWSTR)(pItemEx + 1);
  596. #else
  597.         pszClass = (LPSTR)(pItemEx + 1);
  598. #endif
  599.     }
  600.  
  601.     CRect rect(pItem->x, pItem->y, pItem->x + pItem->cx, pItem->y + pItem->cy);
  602.     ::MapDialogRect(pWndParent->m_hWnd, &rect);
  603.  
  604.     BSTR bstrLicKey = NULL;
  605.  
  606.     // extract license key data, if any
  607.     if (cb >= sizeof(ULONG))
  608.     {
  609.         ULONG cchLicKey = *(UNALIGNED ULONG*)lpData;
  610.         lpData += sizeof(ULONG);
  611.         cb -= sizeof(ULONG);
  612.         if (cchLicKey > 0)
  613.         {
  614.             bstrLicKey = SysAllocStringLen((LPCOLESTR)lpData, cchLicKey);
  615.             lpData += cchLicKey * sizeof(WCHAR);
  616.             cb -= cchLicKey * sizeof(WCHAR);
  617.         }
  618.     }
  619.  
  620.     // If WM_OCC_INITNEW, we should have exhausted all of the data by now.
  621.     ASSERT((nMsg != WM_OCC_INITNEW) || (cb == 0));
  622.  
  623. #if !defined(_WIN32_WCE)
  624.     CDataBoundProperty* pBindings = NULL;
  625.     CString strDataField;
  626.     WORD ctlidRowSource = 0;
  627.     DISPID defdispid = 0;
  628.     UINT dwType = 0;
  629.  
  630.     if (nMsg == WM_OCC_LOADFROMSTREAM_EX ||
  631.         nMsg == WM_OCC_LOADFROMSTORAGE_EX)
  632.     {
  633.         // Read the size of the section
  634.         ULONG cbOffset = *(UNALIGNED ULONG*)lpData;
  635.         ULONG cbBindInfo = cbOffset - sizeof(DWORD);
  636.         lpData += sizeof(DWORD);
  637.  
  638.         ULONG dwFlags = *(UNALIGNED ULONG*)lpData;
  639.         cbBindInfo -= sizeof(DWORD);
  640.         lpData += sizeof(DWORD);
  641.         ASSERT(dwFlags == 1);
  642.  
  643.         // ULONG cbBinding = *(UNALIGNED ULONG*)lpData;
  644.         cbBindInfo -= sizeof(DWORD);
  645.         lpData += sizeof(DWORD);
  646.  
  647.         while (cbBindInfo > 0)
  648.         {
  649.             DISPID dispid;
  650.             UWORD ctlid;
  651.  
  652.             dispid = *(UNALIGNED DISPID *)lpData;
  653.             lpData += sizeof(DISPID);
  654.             cbBindInfo -= sizeof(DISPID);
  655.             ctlid =  *(UNALIGNED WORD *)lpData;
  656.             lpData += sizeof(WORD);
  657.             cbBindInfo -= sizeof(WORD);
  658.  
  659.             if(dispid == DISPID_DATASOURCE)
  660.             {
  661.                 defdispid = *(UNALIGNED ULONG*)lpData;
  662.                 cbBindInfo -= sizeof(DISPID);
  663.                 lpData += sizeof(DISPID);
  664.                 dwType = *(UNALIGNED ULONG*)lpData;
  665.                 cbBindInfo -= sizeof(DWORD);
  666.                 lpData += sizeof(DWORD);
  667.  
  668.                 ASSERT(*(UNALIGNED DISPID *)lpData == DISPID_DATAFIELD);
  669.                 lpData += sizeof(DISPID);
  670.                 cbBindInfo -= sizeof(DISPID);
  671.                 // Skip the string length
  672.                 lpData += sizeof(DWORD);
  673.                 cbBindInfo -= sizeof(DWORD);
  674.                 strDataField = (char *)lpData;
  675.                 lpData += strDataField.GetLength()+1;
  676.                 cbBindInfo -= strDataField.GetLength()+1;
  677.                 ctlidRowSource = ctlid;
  678.             } else
  679.                 pBindings = new CDataBoundProperty(pBindings, dispid, ctlid);
  680.         }
  681.         cb -= cbOffset;
  682.  
  683.         // From now on act as a regular type
  684.         nMsg -= (WM_OCC_LOADFROMSTREAM_EX - WM_OCC_LOADFROMSTREAM);
  685.     }
  686. #endif
  687.  
  688.     GUID clsid;
  689.     HRESULT hr;
  690. #ifndef OLE2ANSI
  691.     if (pszClass[0] == L'{')
  692. #else
  693.     if (pszClass[0] == '{')
  694. #endif
  695.         hr = CLSIDFromString(pszClass, &clsid);
  696.     else
  697.         hr = WCE_FCTN(CLSIDFromProgID)(pszClass, &clsid);
  698.  
  699. #ifdef _DEBUG
  700.     if (FAILED(hr))
  701.     {
  702. #ifndef OLE2ANSI
  703.         TRACE1("Unable to convert \"%ls\" to a class ID.\n", pszClass);
  704. #else
  705.         TRACE1("Unable to convert \"%s\" to a class ID.\n", pszClass);
  706. #endif
  707.         TRACE1(">>> Result code: 0x%08lx\n", hr);
  708.         if (pszClass[0] != L'{')
  709.             TRACE0(">>> Is the control properly registered?\n");
  710.     }
  711. #endif
  712.  
  713.     CMemFile memFile(lpData, cb);
  714.     CMemFile* pMemFile = (nMsg == WM_OCC_INITNEW) ? NULL : &memFile;
  715.  
  716.     COleControlSite* pSite = NULL;
  717.  
  718.     if (SUCCEEDED(hr) &&
  719.         pWndParent->InitControlContainer() &&
  720.         pWndParent->m_pCtrlCont->CreateControl(NULL, clsid, NULL, pItem->style,
  721.             rect, pItem->id, pMemFile, (nMsg == WM_OCC_LOADFROMSTORAGE),
  722.             bstrLicKey, &pSite))
  723.     {
  724.         ASSERT(pSite != NULL);
  725.  
  726.         // freeze events until all controls are loaded
  727.         pSite->FreezeEvents(TRUE);
  728.  
  729.         // set ZOrder only!
  730.         SetWindowPos(pSite->m_hWnd, hwAfter, 0, 0, 0, 0,
  731.             SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  732.  
  733. #if !defined(_WIN32_WCE)
  734.         pSite->m_pBindings = pBindings;
  735.         pSite->m_strDataField = strDataField;
  736.         pSite->m_ctlidRowSource = ctlidRowSource;
  737.         pSite->m_defdispid = defdispid;
  738.         pSite->m_dwType = dwType;
  739.         ICursor* pCursor;
  740.         if (SUCCEEDED(pSite->m_pObject->QueryInterface(IID_ICursor,
  741.             (LPVOID *)&pCursor)))
  742.         {
  743.             pCursor->Release();
  744.         }
  745. #endif // _WIN32_WCE
  746.     }
  747.  
  748.     if (bstrLicKey != NULL)
  749.         SysFreeString(bstrLicKey);
  750.  
  751.     return (pSite != NULL) ? pSite->m_hWnd : NULL;
  752. }
  753.  
  754. /////////////////////////////////////////////////////////////////////////////
  755. // CDataExchange::PrepareOleCtrl
  756.  
  757. CWnd* CDataExchange::PrepareOleCtrl(int nIDC)
  758. {
  759.     ASSERT(nIDC != 0);
  760.     ASSERT(nIDC != -1); // not allowed
  761.     CWnd* pWndCtrl = m_pDlgWnd->GetDlgItem(nIDC);
  762.     if ((pWndCtrl == NULL) || (pWndCtrl->m_hWnd == NULL))
  763.     {
  764.         TRACE1("Error: no data exchange control with ID 0x%04X\n", nIDC);
  765.         ASSERT(FALSE);
  766.         AfxThrowNotSupportedException();
  767.     }
  768.     m_hWndLastControl = pWndCtrl->m_hWnd;
  769.     m_bEditLastControl = FALSE; // not an edit item by default
  770.     return pWndCtrl;
  771. }
  772.  
  773.  
  774. #endif //!_AFX_NO_OCC_SUPPORT
  775.